import { useEffect, useState } from "react";

//文档高度
export function getDocumentTop(): number {
  var scrollTop: number = 0,
    bodyScrollTop: number = 0,
    documentScrollTop: number = 0;
  if (document.body) {
    bodyScrollTop = document.body.scrollTop;
  }
  if (document.documentElement) {
    documentScrollTop = document.documentElement.scrollTop;
  }
  scrollTop = bodyScrollTop - documentScrollTop > 0 ? bodyScrollTop : documentScrollTop;
  return scrollTop;
}

//可视窗口高度
export function getWindowHeight(): number {
  var windowHeight: number = 0;
  if (document.compatMode == "CSS1Compat") {
    windowHeight = document.documentElement.clientHeight;
  } else {
    windowHeight = document.body.clientHeight;
  }
  return windowHeight;
}

//滚动条滚动高度
export function getScrollHeight(): number {
  var scrollHeight: number = 0,
    bodyScrollHeight: number = 0,
    documentScrollHeight: number = 0;
  if (document.body) {
    bodyScrollHeight = document.body.scrollHeight;
  }

  if (document.documentElement) {
    documentScrollHeight = document.documentElement.scrollHeight;
  }
  scrollHeight = bodyScrollHeight - documentScrollHeight > 0 ? bodyScrollHeight : documentScrollHeight;
  return scrollHeight;
}

// 文档高度 + 可视窗口高度 = 滚动条滚动高度   --->   触底


/**
 * 
 * @param shouldUpdate () => {
 *              return {
 *                  topOffset: 距离顶部多少px
 *                  bottomOffset: 距离底部多少px
 *                  scope: [100, 200]  // 监听100-200
 *              }
 *          }
 * @returns {
 *  top: 顶部距离,
 *  scrollH: 滚动条高度,
 *  winH: 视窗高度,
 *  isTop: 是否到顶,
 *  isBottom: 是否到底,
 *}
 */
type ShouldUpdate = () => { topOffset?: number, bottomOffset?: number, scope?: [number, number] }
type Position = {
  top: number,
  scrollH: number,
  winH: number,
  isTop: boolean,
  isBottom: boolean
}
export default function useWindowScrollY(shouldUpdate?: ShouldUpdate): any {
  const top: number = getDocumentTop();
  const scrollH: number = getScrollHeight();
  const winH: number = getWindowHeight();
  const newPosition: Position = {
    top,
    scrollH,
    winH,
    isTop: top === 0,
    isBottom: scrollH === top + winH,
  };
  const [position, setPosition] = useState<Position>(newPosition);

  const listen = () => {
    const top: number = getDocumentTop();
    const scrollH: number = getScrollHeight();
    const winH: number = getWindowHeight();
    const winBottomOffset: number = scrollH - (winH + top);
    const updateCfg: Record<string, any> | undefined = typeof shouldUpdate === 'function' ? shouldUpdate() : undefined;
    const newPosition: Position = {
      top,
      scrollH,
      winH,
      isTop: top === 0,
      isBottom: scrollH === top + winH,
    };
    if (updateCfg instanceof Object && updateCfg !== null) {
      if (
        typeof updateCfg.topOffset === "number" &&
        updateCfg.topOffset > 0 &&
        top >= 0 &&
        top <= updateCfg.topOffset
      ) {
        // 距离顶部设置距离触发
        setPosition({ ...newPosition });
      }

      if (
        typeof updateCfg.bottomOffset === "number" &&
        updateCfg.bottomOffset > 0 &&
        winBottomOffset <= updateCfg.bottomOffset
      ) {
        // 距离底部设置距离触发
        setPosition({ ...newPosition });
      }

      if (
        Array.isArray(updateCfg.scope) &&
        updateCfg.scope.length === 2 &&
        top >= updateCfg.scope[0] &&
        top <= updateCfg.scope[1]
      ) {
        // 在设定范围内触发
        setPosition({ ...newPosition });
      }
    } else {
      setPosition({ ...newPosition });
    }
  };

  useEffect(() => {
    window.addEventListener("scroll", listen);
    return () => window.removeEventListener("scroll", listen);
  }, []);

  return position;
}
